package com.distribute.framework.dao.impl;


import com.distribute.framework.core.web.helper.Utils;
import com.distribute.framework.core.web.util.Page;
import com.distribute.framework.core.util.Function;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;
import javax.annotation.Resource;

import org.mybatis.spring.SqlSessionTemplate;

import com.distribute.framework.plugin.*;
import com.distribute.framework.dao.ITbOfflineZsDao;
import com.distribute.framework.model.TbOfflineZs;
import com.distribute.framework.model.DefineException;


/**
 * 线下招商的Dao实现
 * @author 刘代应
 * 感谢ibatis的持久层框架 
 */
@SuppressWarnings("unchecked")
@Repository(value="tbOfflineZsDao")
public class TbOfflineZsDao implements ITbOfflineZsDao
{
	@Resource
    private SqlSessionTemplate distributeSysSqlSessionTemplate;
	
	
	/************LAZY3Q_DEFINE_CODE************/
	/************LAZY3Q_DEFINE_CODE************/
	
	/**
	 * 自定义加工处理params,可以添加表别名、联表查询等操作
	 * 可在此动态设置数据源，以达到分库分表的目的
	 * @param params
	 * @return
	 */
	private Map custom(Map params){
		
		
		
		
		
		/************LAZY3Q_DAO_CUSTOM************/
		/************LAZY3Q_DAO_CUSTOM************/
		return params;
	}
	
	/**
	 * 自定义加工处理params,可以添加表别名、联表查询等操作
	 * 可在此动态设置数据源，以达到分库分表的目的
	 * @param params
	 * @return
	 */
	private TbOfflineZs custom(TbOfflineZs params){
		
		/************LAZY3Q_CUSTOM_MODEL************/
		/************LAZY3Q_CUSTOM_MODEL************/
		return params;
	}
	
	
	
	/************LAZY3Q_DEFINE_FUNCTION************/
	/************LAZY3Q_DEFINE_FUNCTION************/
	
	/**
	 * 为某些需要加like的key加%
	 * @param params
	 * @return
	 */
	private Map filter(Map params){
		//为模糊匹配的varchar类型字段加上%号
		String[] likes={
		
			
		
			
			"tbozContent"			
			
		
		};
		for(String key:likes){
			String value=(String) params.get(key);
			if(value==null || value.trim().equals(""))
				params.remove(key);
			else
				params.put(key, "%"+value.replaceAll("%", "")+"%");
		}
		
		//如果输入的字串大于设定的长度，并且包含半角逗号的，使用in方法进行查询
		String[] ins={
		
			
			"tbozId"			
			
		
			
		
			
		
		};
		for(String key:ins){
			String value=(""+params.get(key)).replace("%", "");
			if(value.indexOf(",")>-1 && value.startsWith("[") && value.endsWith("]")){
				params.put(key+"In", value.replace("'","''").replace(",", "','").replace("[", "'").replace("]", "'"));
			}
		}
		
		Object[] keys = {};
		keys = params.keySet().toArray(keys);
		for(Object key:keys){
			if(key.toString().endsWith("Not"))continue;
			Object value=params.get(key);
			if(value==null || value.toString().trim().equals(""))
				params.remove(key);
		}
		
		return params;
	}
	

	/**
	 * 获取所有线下招商
	 * @return
	 */	
	public List<TbOfflineZs> getTbOfflineZsList(Map params,Integer offset,Integer size)
	{		
		params = custom(params);
		params.put("SIZE", size);//放入查询条数，作为缓存唯一依据
		String json = params.toString();
		String md5 = Utils.md5(json);
		
		List<TbOfflineZs> list = new ArrayList();
		
		
		
		if(size!=null && size!=-1)
			params.put("limit", size);
		if(offset!=null && params.get("limit")!=null)
			params.put("offset",offset);
		
	
		list = distributeSysSqlSessionTemplate.selectList("getTbOfflineZsList", params);
	
		
		
		
		return list;
	}
	
	
	/**
	 * 获取线下招商统计
	 * @return
	 */
	public List getTbOfflineZsStats(Map params,Map<String,Object> groups,Map<String,Object> sums)
	{
		params = custom(params);
		params=filter(params);
		
		String groupSql="";
		for(Map.Entry<String, Object> item : groups.entrySet())
			if(!Utils.empty(item.getKey()))
				groupSql+=(groupSql.equals("")?"":",")+item.getValue().toString().replace("{key}",item.getKey());
		if(groups.get("definex")!=null)
			groupSql+=(groupSql.equals("")?"":",")+groups.get("definex");
		if(!groupSql.equals(""))
			groupSql = "group by "+groupSql;
		if(params.get("desc")!=null)
			groupSql+=" order by {key} desc ".replace("{key}",params.get("desc").toString());
		else if(params.get("asc")!=null)
			groupSql+=" order by {key} asc ".replace("{key}",params.get("asc").toString());
		if(!groupSql.equals(""))
			groupSql+=" limit 512 ";
			
		String selectSql="count(*) as 'count'";
		for(Map.Entry<String, Object> item : sums.entrySet())
			if(!Utils.empty(item.getKey()))
				selectSql+=(selectSql.equals("")?"":",")+item.getValue().toString().replace("{key}",item.getKey())+(item.getValue().toString().indexOf(" as ")==-1 ? (" as "+item.getKey()) : "");
		for(Map.Entry<String, Object> item : groups.entrySet())
			if(!Utils.empty(item.getKey()))
				selectSql+=(selectSql.equals("")?"":",")+item.getKey()+" as '"+item.getKey()+"'";
		if(sums.get("definex")!=null)
			selectSql+=(selectSql.equals("")?"":",")+sums.get("definex");
		
		params.put("select",selectSql);
		params.put("group",groupSql);
		return distributeSysSqlSessionTemplate.selectList("getTbOfflineZsStats", params);
	}

	/**
	 * 获取线下招商分页
	 * @return
	 */
	public Page getTbOfflineZsPage(int page,int size,Map params)
	{
		params = custom(params);
		params=filter(params);
		
		if(size<1)size=20;
		
		//获取分页总数
		Long count= (Long) distributeSysSqlSessionTemplate.selectOne("getTbOfflineZsCount", params);
		//取分页的队列
		
		params.put("limit", size);
		params.put("offset", (int)Page.test(page,size,count));
		List list=distributeSysSqlSessionTemplate.selectList("getTbOfflineZsPage", params);
		
		//返回一个包装分页对象
		return new Page(page,size,count,list);
	}
	
	/**
	 * 获取线下招商数量
	 * @return
	 */	
	public Long getTbOfflineZsCount(Map params)
	{
		params = custom(params);
		params=filter(params);
		return (Long) distributeSysSqlSessionTemplate.selectOne("getTbOfflineZsCount", params);
	}
	
	/**
	 * 获取线下招商自定义求和表达式,比如求ID平均值:eval="avg(id)"
	 * @return
	 */	
	public <T> T getTbOfflineZsEval(String eval,Map params)
	{
		params = custom(params);
		params=filter(params); 
		params.put("eval",eval);
		Map result = (Map) distributeSysSqlSessionTemplate.selectOne("getTbOfflineZsEval", params);
		return result==null?null:(T)result.get("eval");
	}
	
	
	/**
	 * 根据查询条件取单个线下招商
	 * @param params
	 * @return
	 */
	public TbOfflineZs getTbOfflineZs(Map params)
	{		
		params = custom(params);
		
		
			
		List<TbOfflineZs> list=this.getTbOfflineZsList(params,0,1);
		TbOfflineZs tbOfflineZs = list.isEmpty()?null:list.get(0);
		
		
		if(tbOfflineZs!=null)
			Cache.setValue(TbOfflineZs.class,tbOfflineZs.getId(), tbOfflineZs.getKeyValue());
		
		
		
		return tbOfflineZs;
	}
		
	/**
	 * 根据ID取线下招商
	 * @param id
	 * @return
	 */
	public TbOfflineZs getTbOfflineZsById(Long id)
	{
		
		if(id==null)
			return null;
		
	
		TbOfflineZs tbOfflineZs = null;
		if(tbOfflineZs!=null)
			return tbOfflineZs;
		if(tbOfflineZs!=null && tbOfflineZs.getTbozId()==null)
			return null;
			
		Map params=new HashMap();
		params.put("id", id);
		params = custom(params);
		tbOfflineZs = (TbOfflineZs) distributeSysSqlSessionTemplate.selectOne("getTbOfflineZsById",params);
		
		if(tbOfflineZs!=null)
			Cache.setValue(TbOfflineZs.class,id, tbOfflineZs.getKeyValue());
		else
			Cache.setValue(TbOfflineZs.class,id, "　" );
		
		
		return tbOfflineZs;
	}
	
	/**
	 * 根据ID取线下招商(不缓存)
	 * @param id
	 * @return
	 */
	public TbOfflineZs GetTbOfflineZsById(Long id){
		Map params=new HashMap();
		params.put("id", id);
		params = custom(params);
		return  (TbOfflineZs) distributeSysSqlSessionTemplate.selectOne("getTbOfflineZsById",params);
	}
	

	/**
	 * 保存线下招商
	 * @param tbOfflineZs
	 */
	public TbOfflineZs saveTbOfflineZs(TbOfflineZs tbOfflineZs)
	{
		tbOfflineZs = custom(tbOfflineZs);
		
		Trigger.on(TbOfflineZs.class,Trigger.BEFOR,Trigger.SAVE,tbOfflineZs);
		
		distributeSysSqlSessionTemplate.insert("saveTbOfflineZs", tbOfflineZs);
		Long id=tbOfflineZs.getTbozId();
		
		Cache.setValue(TbOfflineZs.class,id, tbOfflineZs.getKeyValue());
		
		
		
		
		return Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.SAVE,tbOfflineZs);
		
	}

	

	/**
	 * 更新线下招商
	 * @param tbOfflineZs
	 */
	public int updateTbOfflineZs(TbOfflineZs tbOfflineZs)
	{
		tbOfflineZs = custom(tbOfflineZs);
		TbOfflineZs dbTbOfflineZs = TbOfflineZs.get(tbOfflineZs.getId());
		
		Trigger.on(TbOfflineZs.class,Trigger.BEFOR,Trigger.UPDATE,tbOfflineZs);
		
		int rows = distributeSysSqlSessionTemplate.update("updateTbOfflineZs", tbOfflineZs);
		//tbOfflineZs = this.GetTbOfflineZsById(tbOfflineZs.getTbozId());
		
		if(tbOfflineZs!=null){
			
			Cache.setValue(TbOfflineZs.class,tbOfflineZs.getTbozId(), tbOfflineZs.getKeyValue());
			
			
		}
		
		
		
		Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.UPDATE,tbOfflineZs);
		Trigger.on(TbOfflineZs.class,dbTbOfflineZs,tbOfflineZs);
		
		return rows;
	}
	/**
	 * 更新线下招商非空字段
	 * @param tbOfflineZs
	 */
	public int updateTbOfflineZs$NotNull(TbOfflineZs tbOfflineZs)
	{
		tbOfflineZs = custom(tbOfflineZs);
		TbOfflineZs dbTbOfflineZs = TbOfflineZs.get(tbOfflineZs.getId());
		TbOfflineZs updated = tbOfflineZs;
		
		Trigger.on(TbOfflineZs.class,Trigger.BEFOR,Trigger.UPDATE_NOTNULL,updated);
		
		int rows = distributeSysSqlSessionTemplate.update("updateTbOfflineZs$NotNull", tbOfflineZs);
		tbOfflineZs = this.GetTbOfflineZsById(tbOfflineZs.getTbozId());
		
		if(tbOfflineZs!=null){
			
			Cache.setValue(TbOfflineZs.class,tbOfflineZs.getTbozId(), tbOfflineZs.getKeyValue());
			
			
		}
		
		
		updated.setValues("$NotNull", true);
		
		Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.UPDATE_NOTNULL,updated);
		Trigger.on(TbOfflineZs.class,dbTbOfflineZs,tbOfflineZs);
		
		return rows;
	}
	
	
	
	/**
	 * 根据条件更新线下招商
	 * @param values
	 * @param params
	 */
	public int updateTbOfflineZsByConfirm(Map values, Map params){
	
		params = custom(params);
		
		for(Map.Entry<String,Object> entry:((Map<String,Object>)values).entrySet())
			params.put("V_"+entry.getKey(), entry.getValue());
		
		Long count = this.getTbOfflineZsCount(params);
		
		
		Trigger.on(TbOfflineZs.class,Trigger.BEFOR,Trigger.UPDATE_BY,params);
		List<TbOfflineZs> updates = new ArrayList();
		if(count<32 && Trigger.have(TbOfflineZs.class,params)){
			updates = getTbOfflineZsList(params,0,32);
		}
		
		
		//如果更新条数大于255，则清空缓存
		if(count>255){
			if(!Utils.equals(""+params.get("batchUpdatePassword"), "true")){
				throw new DefineException("一次更新超过255,但未输入密码");
			}
			
			Cache.clearValue(TbOfflineZs.class);
			
			
		}else{
			params.put("eval","tboz_id");
			List<Map> result = distributeSysSqlSessionTemplate.selectList("getTbOfflineZsEval", params);
			for(Map map:result){
				
				Cache.deleteValue(TbOfflineZs.class, map.get("eval"));
				
				
			}
		}
		
		
			
		int rows = distributeSysSqlSessionTemplate.update("updateTbOfflineZsBy", params);
		
		
		if(rows==1){
			Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.UPDATE,getTbOfflineZs(params));
		}else{
			Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.UPDATE_BY,params);
		}
		if(count<32 && rows>0 && updates.size()>0){
			Map<Long,TbOfflineZs> mapping = new HashMap();
			String ids = "";
			for(TbOfflineZs tbOfflineZs:updates){
				mapping.put(tbOfflineZs.getId(), tbOfflineZs);
				ids+=(ids.equals("")?"":",")+tbOfflineZs.getId();
			}
			updates = TbOfflineZs.where.tbozIdIn(ids).list(32);
			for(TbOfflineZs tbOfflineZs:updates){
				Trigger.on(TbOfflineZs.class,mapping.get(tbOfflineZs.getId()),tbOfflineZs);
			}
		}
		
		
		return rows;
	}
	
	

	/**
	 * 根据ID删除一个线下招商
	 * @param id
	 */
	public void deleteTbOfflineZsById(Long id)
	{
		Map params=new HashMap();
		params.put("tbozId", id);
		params.put("id", id);
		params = custom(params);
		
		Trigger.on(TbOfflineZs.class,Trigger.BEFOR,Trigger.DELETE,params);
		
		distributeSysSqlSessionTemplate.delete("deleteTbOfflineZsById", params);
		
		Cache.deleteValue(TbOfflineZs.class, id);
		
		
		
		
		Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.DELETE,params);
		
	}
	
	
	/**
	 * 根据条件删除线下招商
	 * @param params
	 */
	public void deleteTbOfflineZsByConfirm(Map params){
	
		params = custom(params);
		
		Trigger.on(TbOfflineZs.class,Trigger.BEFOR,Trigger.DELETE_BY,params);
		
		
		//如果更新条数大于255，则清空缓存
		if(this.getTbOfflineZsCount(params)>255){
			if(!Utils.equals(""+params.get("batchDeletePassword"), "true")){ 
				throw new DefineException("一次删除超过255,但未输入密码");
			}
			
			Cache.clearValue(TbOfflineZs.class);
			
			
		}else{
			params.put("eval","tboz_id");
			List<Map> result = distributeSysSqlSessionTemplate.selectList("getTbOfflineZsEval", params);
			for(Map map:result){
				
				Cache.deleteValue(TbOfflineZs.class, map.get("eval"));
				
				
			}
		}
		
		
		
		int rows = distributeSysSqlSessionTemplate.update("deleteTbOfflineZsBy", params);
		
		Trigger.on(TbOfflineZs.class,Trigger.AFTER,Trigger.DELETE_BY,params);
	}
	
	
	/**
	 * 事务处理
	 */
	public <T> T executeTransaction(Function function) {
		return function.execute();	
	}

}